package sf.database.jdbc.type;

import sf.database.dialect.DBDialect;
import sf.database.support.DBMS;
import sf.database.util.DBUtils;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

/**
 * 布尔适配器
 * <p>
 * 对 Oracle，Types.BOOLEAN 对于 setNull 是不工作的 因此 OracleExpert 会用一个新的
 * Adaptor 处理自己这种特殊情况
 */
public class BooleanType implements TypeHandler<Boolean> {
    public Boolean get(ResultSet rs, String colName) throws SQLException {
        boolean re = rs.getBoolean(colName);
        return rs.wasNull() ? null : re;
    }

    public Boolean get(ResultSet rs, int index) throws SQLException {
        boolean re = rs.getBoolean(index);
        return rs.wasNull() ? null : re;
    }

    public Boolean get(CallableStatement cs, int index) throws SQLException {
        boolean re = cs.getBoolean(index);
        return cs.wasNull() ? null : re;
    }

    @Override
    public Boolean get(CallableStatement cs, String parameterName) throws SQLException {
        boolean re = cs.getBoolean(parameterName);
        return cs.wasNull() ? null : re;
    }

    /**
     * Oracle，Types.BOOLEAN 对于 setNull 是不工作的
     * @param stat
     * @param obj
     * @param i
     * @return
     * @throws SQLException
     */
    public Object set(PreparedStatement stat, Object obj, int i) throws SQLException {
        if (null == obj) {
            //oracle需要特殊处理.
            DBDialect dialect = DBUtils.doGetDialect(stat.getConnection(), false);
            if (DBMS.oracle.getNumber() == dialect.getNumber()) {
                stat.setNull(i, Types.INTEGER);
            } else {
                stat.setNull(i, getSqlType());
            }
        } else {
            stat.setBoolean(i, (Boolean) obj);
        }
        return null;
    }

    /**
     * @param cs
     * @param obj
     * @param parameterName
     * @return
     * @throws SQLException
     */
    @Override
    public Object set(CallableStatement cs, Object obj, String parameterName) throws SQLException {
        if (null == obj) {
            //oracle需要特殊处理.
            DBDialect dialect = DBUtils.doGetDialect(cs.getConnection(), false);
            if (DBMS.oracle.getNumber() == dialect.getNumber()) {
                cs.setNull(parameterName, Types.INTEGER);
            } else {
                cs.setNull(parameterName, getSqlType());
            }
        } else {
            cs.setBoolean(parameterName, (Boolean) obj);
        }
        return null;
    }

    @Override
    public void update(ResultSet rs, String columnLabel, Object value) throws SQLException {
        rs.updateBoolean(columnLabel, (Boolean) value);
    }

    @Override
    public void update(ResultSet rs, int columnIndex, Object value) throws SQLException {
        rs.updateBoolean(columnIndex, (Boolean) value);
    }

    @Override
    public int getSqlType() {
        return Types.BOOLEAN;
    }

    @Override
    public Class<Boolean> getDefaultJavaType() {
        return Boolean.class;
    }

}
